Workbench 1.0.0: engine, web UI, CLI, tooling and docs - #4
Conversation
… hardened routes - cache compiled binaries by compiler/std/flags/source with LRU eviction and in-flight coalescing; report cached, diagnostics and rejectedFlags on every compile - parse gcc/clang stderr into structured line/column diagnostics - add tokens and float checkers next to the lines checker and flag presentation-only mismatches - parse pasted Codeforces/AtCoder statements into samples and limits (POST /api/samples) - validate compiler flags against an allowlist; reject path traversal in /api/solution and /api/problem-text; 400 on malformed JSON everywhere - store: atomic writes, whole-workspace records, duplicate, export/import - /api/test: checker, epsilon, stopOnFirstFailure, SKIPPED, timing summary - /api/stress: compilerFlags, checker, seedBase, elapsed and timing stats, 60s budget - /api/config: version, compiler version, limits, cache size and reset - vitest unit suite covering the engine against the real compiler
… full-workspace library - editor: gutter error/warning markers, clickable diagnostics that jump to the line, error/warning counts, cursor status bar, Ctrl+/ comment toggle - run panel: cached-compile marker, diagnostics list, ignored-flag notice, copy and clear, persisted stdin - tests panel: import samples from a pasted statement, run a single case, duplicate, use as stdin, expand/collapse all, stop on first failure, whitespace-only hints, SKIPPED verdicts, max time - stress panel: seed base, timing stats, budget notice, add the failing input as a test case or as stdin - settings: checker mode and epsilon, reset, clear compile cache, server info - sidebar: whole-workspace save (code, tests, stdin, stress, settings), duplicate, filter, relative timestamps, dirty indicator, new workspace, export/import; constrain width so long names cannot overflow into the editor - resizable editor/panel split, remembered tab, Ctrl+1..4 and Ctrl+B shortcuts, compiler shown in the header, offline-aware API client - five new Playwright specs; remove the unused lib/cf.ts and scaffold SVGs
- new commands: stress (solution vs brute.cpp on gen.cpp inputs, saves the first counter-example), samples, watch, doctor, clean, version; `new` as an alias for template - template --from dp|graph|math|<file> - --checker lines|tokens (or CF_CHECKER) on run/test/stress with a hint when only whitespace differs; --timeout; per-sample and max timing in cf test - explicit problem argument wins over the cwd in cf test; brute/gen sources are excluded from the solution build; CF_CXX/CXX, NO_COLOR, CF_NO_EDITOR, CF_SERVE_PROD; cf update pulls --ff-only - tests/cli_test.sh: 57 end-to-end checks against the real compiler, replacing tests/parser_test.sh and test_full.sh - scripts/test.sh: report the real exit status (was the negated `if !` result), delegate to the CLI suite, shellcheck clean
- scripts/check.sh and `make check`: shellcheck, CLI tests, lint, typecheck, unit tests, production build and a CLI/web version-consistency check - Makefile: check, check-quick, validate and web-* targets; shared source resolution for build/run/test/debug - GitHub Actions CI on Ubuntu and macOS (CLI, web, Playwright) and a release workflow that publishes the CHANGELOG section for a pushed v* tag - .gitattributes pins LF for scripts and C++ sources so Windows checkouts run unchanged
…oubleshooting) - README: CLI and workbench feature overview, quick start for both, updated repository map and command table - docs: every new panel feature, CLI command and option; the compile cache, checkers, statement parser, flag allowlist and store in architecture.md; every route contract in api.md; quality gates, test suites, CI and the release procedure in development.md; new troubleshooting entries for ignored flags, the cache, checkers, statement import and Windows - CHANGELOG.md for 1.0.0; CONTRIBUTING reflects the test layers and gate; SECURITY describes the local-only threat model and private reporting
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ebfc392c20
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| while IFS= read -r file; do | ||
| [ -n "$file" ] && cpp_files+=("$file") | ||
| done < <(find "$src_ctx" -maxdepth 1 -name "*.cpp" -type f 2>/dev/null) | ||
| collect_cpp_files "$src_ctx" |
There was a problem hiding this comment.
Exclude stress helper mains from normal runs
When a problem contains the documented solution.cpp, brute.cpp, and gen.cpp stress setup, cmd_run passes all three files returned by collect_cpp_files to one compiler invocation. Since each normally defines main, cf and cf <problem> fail with duplicate-symbol linker errors; apply the same helper-file filtering already used by cmd_test_all and cmd_stress.
Useful? React with 👍 / 👎.
| started=$(now_ms) | ||
| for ((i=0; i<iterations; i++)); do | ||
| seed=$((seed_base + i)) | ||
| if ! "$gen_bin" "$seed" > "$input_tmp" 2>/dev/null; then |
There was a problem hiding this comment.
Apply the timeout to the stress generator
In cmd_stress, the solution and brute are executed through safe_execute, but the generator is invoked directly. A generator that loops or stalls therefore ignores --timeout/CF_TIMEOUT and hangs the entire stress command indefinitely; run it through the same timeout wrapper while preserving the seed argument.
Useful? React with 👍 / 👎.
| child.stdout.on("data", (d: Buffer) => { | ||
| if (stdout.length >= maxOut) return; | ||
| stdout += d.toString("utf8"); | ||
| if (stdout.length >= maxOut) { | ||
| stdout = stdout.slice(0, maxOut); | ||
| if (outLen >= maxOut) return; |
There was a problem hiding this comment.
Detect output overflow at the exact byte cap
If a stdout chunk fills the remaining buffer exactly, the else branch sets outLen to maxOut without marking truncation or killing the child. Every later chunk then returns here immediately, so a runaway writer can continue until the time limit and is reported as an untruncated TLE instead of being stopped at the output cap. The cap check must also handle the case where the accumulated length is already equal to the limit.
Useful? React with 👍 / 👎.
| generator: problem.generator || DEFAULT_STRESS.generator, | ||
| iterations: stress.iterations, | ||
| }; | ||
| const nextStdin = problem.stdin || problem.tests[0]?.input || ""; |
There was a problem hiding this comment.
Preserve an intentionally empty stdin on load
When a saved workspace deliberately has an empty stdin, loading it replaces that value with the first test case's input because the empty string is treated as missing by ||. This means save/reset/load does not round-trip the workspace state; fallback to the sample should only occur for legacy records where the field is absent, not when it is explicitly empty.
Useful? React with 👍 / 👎.
| code, | ||
| tests: toTestCases(tests), |
There was a problem hiding this comment.
Include the imported statement in workspace saves
The new statement-import flow retains only the parsed tests and limits, while this workspace payload still omits statement. After the import dialog clears its local text, saving or exporting the problem therefore stores an empty statement even though the problem model and whole-workspace feature include that field. Keep the pasted statement in page state and include it in the save/load snapshot.
Useful? React with 👍 / 👎.
…chunks
- include/bits/stdc++.h: only pull in <coroutine> under C++20 (or
-fcoroutines); libstdc++ 13 rejects it outright with -std=gnu++17, which
broke the Makefile smoke test and every compile in the web unit tests
- scripts/cf: expand the cleanup and source-file arrays with the
${arr[@]+"${arr[@]}"} idiom so an empty array does not trip `set -u` on
bash 3.2; the EXIT trap made `cf version` exit 1 on macOS
- tests/cli_test.sh: record assertion results with && instead of a bare
test so a failing check is reported rather than aborting the suite
silently under `set -e`
- engine: when a stdout/stderr chunk fills the output cap exactly, flag the
next chunk as truncation and stop the program; macOS delivered a 64 KiB
chunk that exactly matched the cap and the run was never marked truncated
A side-effect-free `for(;;){}` is undefined behaviour in C++ and gcc 13 at
-O2 on the ubuntu runner deleted it, so the binary returned immediately and
`timedOut` was false. A volatile counter keeps the loop observable on every
compiler.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Summary
Takes the workbench from an untagged prototype to 1.0.0: a rewritten execution
engine, a substantially expanded web UI, a full-featured CLI, a quality gate,
CI and a release workflow, and rewritten documentation.
structured gcc/clang diagnostics, compiler-flag allowlist,
lines/tokens/floatoutput checkers with presentation-only detection, Codeforces/AtCoderstatement parser, atomic whole-workspace problem store with export/import
and path-traversal validation, Windows support.
runs, stress counter-example promotion, checker settings, resizable split,
keyboard shortcuts, offline-aware API client, full-workspace library.
stress,samples,watch,doctor,clean,version,checkers, timeouts and per-sample timing; 57 end-to-end checks.
make checkgate (shellcheck, CLI tests, lint, typecheck, unittests, build, version consistency), GitHub Actions CI on Ubuntu and macOS,
tag-driven release workflow, LF line endings pinned.
docs/setrewritten for 1.0.0.
Verification
make check: shellcheck clean, 57/57 CLI checks, lint and typecheck clean,63/63 unit tests, production build, version consistency
See CHANGELOG.md for the full 1.0.0 entry.